
using System;

namespace OverLoad 
{

    public delegate string MyDelegate(int c, string s);


    public class TestClass
    {
        public static int x = 10;

        public static int GetX()
        {
            return x;
        }

        public TestClass()
        {
            y = 42;
        }

        public TestClass(int y)
        {
            this.y = y;
        }

        public TestClass(TestClass cl)
        {
            if (cl == null)
                this.y = 42;
            else
                this.y = cl.y;
        }

        public int y;
        public int theY
        {
            get { return y; }
            set { y = value; }
        }

        public int GetY() { return y; }
        public void SetY(int newy)
        {
            y = newy;
        }

        public void GetRefY(ref int param)
        {
            param = y;
        }

        public TType Identity<TType>(TType n)
        {
            return n;
        }
        
        public string Callback(int c, string s)
        {
            this.y = c;
            return s;
        }

        public MyDelegate GetCallback()
        {
            return new MyDelegate(Callback);
        }

        public string GetResult()
        {
            return y.ToString();
        }
    }


    public class GenericTestClass<T, U>
    {
        private T t;
        private U u;

        public T theT
        {
            get { return t; }
            set { t = value; }
        }

        public U theU
        {
            get { return u; }
            set { u = value; }
        }

        public GenericTestClass(T t, U u)
        {
            this.t = t;
            this.u = u;
        }

        public string GetResult()
        {
            return t.ToString() + u.ToString();
        }
    }


    public class Over
    {
	    private int val;

	    public Over() { val = 0; }
	    public Over(int n) { val = n; }
    	
	    public override string ToString()
	    {
		    return val.ToString();
	    }

	    public static explicit operator Over (int n) 
	    { 
		    Console.WriteLine("explicit");
		    return new Over(n); 
	    }

	    public static implicit operator Over (string s) 
	    {
		    Console.WriteLine("implicit");
		    return new Over(Int32.Parse(s));
	    }
    	
	    public static Over operator + (Over a, Over b)
	    {
		    Console.WriteLine("addition");
		    return new Over(a.val + b.val);
	    }
    	
	    public static Over operator - (Over a, Over b)
	    {
		    Console.WriteLine("subtraction");
		    return new Over(a.val - b.val);
	    }
    	
	    public static Over operator * (Over a, Over b)
	    {
		    Console.WriteLine("multiply");
		    return new Over(a.val * b.val);
	    }

	    public static Over operator / (Over a, Over b)
	    {
		    Console.WriteLine("division");
		    return new Over(a.val / b.val);
	    }

	    public static Over operator ++ (Over a)
	    {
		    Console.WriteLine("increment");
		    ++a.val;
		    return a;
	    }

	    public static Over operator -- (Over a)
	    {
		    Console.WriteLine("decrement");
		    --a.val;
		    return a;
	    }
    	
	    public static bool operator < (Over a, Over b)
	    {
		    Console.WriteLine("less-than");
		    return a.val < b.val;
	    }

	    public static bool operator <= (Over a, Over b)
	    {
		    Console.WriteLine("less-than-or-equal");
		    return a.val <= b.val;
	    }

	    public static bool operator >= (Over a, Over b)
	    {
		    Console.WriteLine("greater-than-or-equal");
		    return a.val >= b.val;
	    }

	    public static bool operator > (Over a, Over b)
	    {
		    Console.WriteLine("greater-than");
		    return a.val > b.val;
	    }
    	
	    public static Over operator | (Over a, Over b)
	    {
		    Console.WriteLine("bitwise-or");
		    return new Over(a.val | b.val);
	    }
    	
	    public static Over operator & (Over a, Over b)
	    {
		    Console.WriteLine("bitwise-and");
		    return new Over(a.val & b.val);
	    }
    	
	    public static Over operator ^ (Over a, Over b)
	    {
		    Console.WriteLine("exclusive-or");
		    return new Over(a.val ^ b.val);
	    }
    	
	    public static Over operator ~ (Over a)
	    {
		    Console.WriteLine("Ones-complement");
		    return new Over(~a.val);
	    }
    }
}
